import LogService from "./LogService";
import DeviceConfig from "@/config/DeviceConfig";
import {
	BuffUtils
} from "@/utils/BuffUtils";
import MessageConfig from "@/config/MessageConfig";
import EventUtils from "@/utils/EventUtils";
import { showInfo } from "@/utils/ToastUtils";

class BluDeviceComService {

	deviceConnected = new Map();
	MTU = 182;

	onBLEConnectionStateChange = (res) => {
		const {
			deviceId,
			connected
		} = res;
		console.log(`device ${deviceId} state has changed, connected: ${connected}`);
		if (!connected)
			EventUtils.trigger(MessageConfig.BlE_CONNECT_TYPE, res);
	}

	constructor(props) {
		uni.onBLEConnectionStateChange(this.onBLEConnectionStateChange);
	}

	async connetBlue(deviceId) {
		LogService.debug("开始连接设备", deviceId);
		await this.disconnetBlue(deviceId);
		LogService.debug("查看设备列表");
		await this.getConBluetoothDevices();

		DeviceConfig.IS_OTA = false;

		try {
			let res = await uni.createBLEConnection({
				deviceId,
			});
			LogService.debug("createBLEConnection success", res);

			// const deviceInfo = Taro.getDeviceInfo();
			// if (deviceInfo.platform == 'android') {
			//   res = await Taro.setBLEMTU({deviceId, mtu: 512});
			//   LogService.debug("setBLEMTU success", res);
			//   this.MTU = 500;
			// }
			setTimeout(async () => {
				await this.getBLEDeviceServices(deviceId);
				LogService.debug("awit");
				await this.lisBluData(deviceId);
				EventUtils.trigger(MessageConfig.BlE_CONNECT_TYPE, {
					deviceId,
					connected: true
				});
			}, 2000);
			return true;
		} catch (e) {
			LogService.error("createBLEConnection fail", e)
			showInfo(JSON.stringify(e));
			// EventUtils.trigger(MessageConfig.BlE_CONNECT_TYPE, {deviceId, connected: false});
			return false;
		}
	}

	async closeBluetoothAdapter() {
		try {
			const res = await uni.closeBluetoothAdapter({
				success: function(res) {
					console.log(res)
				}
			})
			LogService.debug("closeBluetoothAdapter success", res);
		} catch (e) {
			LogService.error("closeBluetoothAdapter fail", e);
			return false;
		}
	}

	async disconnetBlue(deviceId) {
		try {
			console.log("断开设备连接", deviceId);
			const res = await uni.closeBLEConnection({
				deviceId,
				success: function(resoure) {
					console.log("断开成功", resoure);
				},
				fail: function(e) {
					console.log("断开失败", e);
				}
			});
			LogService.debug("closeBLEConnection success", deviceId, res);
			return true;
		} catch (e) {
			LogService.error("closeBLEConnection fail", deviceId, e);
			return false;
		}
	}

	async getConBluetoothDevices() {
		try {
			const res = await uni.getConnectedBluetoothDevices();
			LogService.debug("getConnectedBluetoothDevices success", res);
			return true;
		} catch (e) {
			LogService.error("getConnectedBluetoothDevices fail", e);
			return false;
		}
	}

	/**
	 * 获取服务名称和特征uuid
	 * @param deviceId
	 */
	async getBLEDeviceServices(deviceId) {
		try {
			const res = await uni.getBLEDeviceServices({
				// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
				deviceId
			});
			LogService.debug("getBLEDeviceServices sucess", deviceId, res);
			// showInfo(JSON.stringify(res.services));
			// console.log("getBLEDeviceServices res",res[1].services);
			// for (let i = 0; i < res[1].services.length; i++) {
			// 	let value = res[1].services[i];
			// 	console.log("getBLEDeviceServices value",value,DeviceConfig.Service_UUID);
			// 	const {uuid} = value;
			// 	await this.getCharacteristics(deviceId, uuid);
			// }
			for (let i = 0; i < res.services.length; i++) {
				let value = res.services[i];
				const {
					uuid
				} = value;
				await this.getCharacteristics(deviceId, uuid);
			}
			LogService.debug("getBLEDeviceServices end");
		} catch (e) {
			console.log("获取服务失败");
			showInfo(JSON.stringify(e));
			LogService.error("getBLEDeviceServices fail", deviceId, e);
		}
	}

	async getCharacteristics(deviceId, uuid) {
		try {
			const res = await uni.getBLEDeviceCharacteristics({
				// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
				deviceId,
				// 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
				serviceId: uuid,
			});
			// showInfo(JSON.stringify(res.characteristics))
			LogService.debug('device getBLEDeviceCharacteristics sucess:', res.characteristics)
		} catch (e) {
			console.log("获取特征值失败");
			showInfo(JSON.stringify(e));
			LogService.error('device getBLEDeviceCharacteristics fail:', e);
		}
	}

	/**
	 * 监听接收数据
	 * @param deviceId
	 */
	lisBluData(deviceId) {

		let promise = new Promise(function(resolve, reject) {
			//resolve,   成功调用
			//reject     失败调用
			uni.notifyBLECharacteristicValueChange({
				state: true, // 启用 notify 功能
				// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
				deviceId,
				// 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
				serviceId: DeviceConfig.Service_UUID,
				// 这里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取
				characteristicId: DeviceConfig.NOTIFY_UUID,
				success: function(res1) {
					LogService.debug("notifyBLECharacteristicValueChange success", res1);
					// 监听设备发过来的数据
					uni.onBLECharacteristicValueChange(function(res) {
						const {
							characteristicId,
							value,
							deviceId
						} = res;
						let data = BuffUtils.buffToArr(value);
						LogService.debug("onBLECharacteristicValueChange:", deviceId,
							BuffUtils.to16(data));
						EventUtils.trigger(MessageConfig.BlE_RECV_TYPE, {
							data,
							sucess: true,
							deviceId
						});
					})
					resolve();
				},
				fail: function(res) {
					console.log("监听通知失败");
					showInfo(JSON.stringify(res));
					LogService.error("notifyBLECharacteristicValueChange fail", res);
					reject(res);
				}
			})
		});
		return promise;
	}

	readData(deviceId, characteristicId) {
		uni.readBLECharacteristicValue({
			// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
			deviceId,
			// 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
			serviceId: Service_UUID,
			// 这里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取
			characteristicId,
			success: function(res) {
				LogService.debug('readBLECharacteristicValue:', res)
			}
		})
	}

	/**
	 * 向蓝牙设备发送一个0x00的16进制数据
	 * let buffer = new ArrayBuffer(1)
	 * @param deviceId
	 * @param arr
	 */
	async sendData(deviceId, arr) {

		let index = 0;
		while (true) {
			let temp = [];
			let i = 0;
			for (; i < this.MTU && index < arr.length; i++) {
				temp.push(arr[index++]);
			}

			if (i == 0) {
				break;
			}

			let buffer = BuffUtils.arrToBuffer(temp);
			let res;
			try {
				res = await uni.writeBLECharacteristicValue({
					// 这里的 deviceId 需要在 getBluetoothDevices 或 onBluetoothDeviceFound 接口中获取
					deviceId,
					// 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
					serviceId: DeviceConfig.Service_UUID,
					// 这里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取
					characteristicId: DeviceConfig.WRITE_NO_ESPONSE_UUID,
					// 这里的value是ArrayBuffer类型
					value: buffer,
				});
			} catch (e) {
				LogService.error('writeBLECharacteristicValue fail', deviceId,
					DeviceConfig.Service_UUID,
					DeviceConfig.WRITE_NO_ESPONSE_UUID,
					arr, e);
				EventUtils.trigger(MessageConfig.BlE_SEND_TYPE, {
					data: arr,
					sucess: false,
					deviceId
				})
				return false;
			}
			LogService.debug("sendData index:" + index);
		}

		LogService.debug('writeBLECharacteristicValue success', deviceId, arr);
		EventUtils.trigger(MessageConfig.BlE_SEND_TYPE, {
			data: arr,
			sucess: true,
			deviceId
		})
		return true;
	}
}

export default new BluDeviceComService();
